package com.spdd.mt.app.aop;

import cn.hutool.core.collection.CollectionUtil;
import com.spdd.mt.biz.manager.feishu.FeiShuService;
import com.spdd.mt.biz.manager.model.WebResponse;
import com.spdd.mt.biz.constant.MtResponseStatus;
import com.spdd.mt.biz.constant.ResponseCode;
import com.spdd.mt.biz.exception.BusinessException;
import com.spdd.mt.biz.exception.SignException;
import com.spdd.mt.biz.util.ThreadLocalContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.multipart.support.MissingServletRequestPartException;

import java.util.Objects;

@Slf4j
@RestControllerAdvice
public class ResultProAdvice {

    @Autowired
    private FeiShuService feiShuService;

    @ResponseBody
    @ExceptionHandler(Exception.class)
    public WebResponse handleException(Exception e) {
        WebResponse res = ThreadLocalContext.RECHARGE_DATA_THREAD_LOCAL.get();

        if (e instanceof MissingServletRequestParameterException
                || e instanceof MissingServletRequestPartException
                || e instanceof MethodArgumentConversionNotSupportedException
                || e instanceof MethodArgumentTypeMismatchException) {
            log.error(e.getClass() + " Exception", e);
            if (Objects.nonNull(res)) {
                res.setStatus(String.valueOf(ResponseCode.PARAM_ERROR.getValue()));
                res.setMsg(ResponseCode.PARAM_ERROR.getDesc());
            }
            return WebResponse.fail(ResponseCode.PARAM_ERROR.getValue(), MtResponseStatus.FAIL.getValue(), ResponseCode.PARAM_ERROR.getDesc());
        } else if (e instanceof SignException) { // 签名异常
            log.error("SignException", e);

            if (Objects.nonNull(res)) {
                res.setStatus(String.valueOf(ResponseCode.PARAM_SIGN_ERROR.getValue()));
                res.setMsg(ResponseCode.PARAM_SIGN_ERROR.getDesc());
            }
            return WebResponse.fail(((SignException) e).getCode(), MtResponseStatus.FAIL.getValue(), e.getMessage());
        } else if (e instanceof BusinessException) {
            log.error("BusinessException", e);
            if (((BusinessException) e).getSendAlarm()) {
                feiShuService.sendExceptionMsg(e);
            }
            if (Objects.nonNull(res)) {
                res.setStatus(String.valueOf(((BusinessException) e).getResponseCode().getValue()));
                res.setMsg(((BusinessException) e).getResponseCode().getDesc());
            }
            return WebResponse.fail(((BusinessException) e).getResponseCode().getValue(), MtResponseStatus.FAIL.getValue(), e.getMessage());
        } else if (e instanceof MethodArgumentNotValidException ex) {
            // String errorMsg = ex.getBindingResult().getAllErrors().stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(","));
            // log.error(errorMsg, e);

            BindingResult bindingResult = ex.getBindingResult();
            String errorMsg = "参数错误";
            if (bindingResult.hasErrors() && CollectionUtil.isNotEmpty(bindingResult.getAllErrors())) {
                // 返回第一条错误
                errorMsg = bindingResult.getAllErrors().get(0).getDefaultMessage();
                //     String messages = bindingResult.getAllErrors()
                //             .stream()
                //             .map(ObjectError::getDefaultMessage)
                //             .reduce((m1, m2) -> m1 + "；" + m2)
                //             .orElse("参数输入有误！");
                //     //这里可以抛出自定义异常,或者进行其他操作
                //     throw new IllegalArgumentException(messages);
                // }
            }
            if (Objects.nonNull(res)) {
                res.setStatus(String.valueOf(ResponseCode.PARAM_ERROR.getValue()));
                res.setMsg(ResponseCode.PARAM_ERROR.getDesc());
            }
            return WebResponse.fail(ResponseCode.PARAM_ERROR.getValue(), MtResponseStatus.FAIL.getValue(), errorMsg);
        } else {
            log.error("Exception", e);
            feiShuService.sendExceptionMsg(e);
            if (Objects.nonNull(res)) {
                res.setStatus(String.valueOf(ResponseCode.INNER_ERROR.getValue()));
                res.setMsg(ResponseCode.INNER_ERROR.getDesc());
            }
            return WebResponse.fail(ResponseCode.INNER_ERROR.getValue(), MtResponseStatus.FAIL.getValue(), ResponseCode.INNER_ERROR.getDesc());
        }
    }
}
